/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { onMounted, onUnmounted, Ref, ref } from 'vue';
import dayjs from 'dayjs';
import Variables from '../constant/vars';
import { debounce } from '../utils';
import useStore from '../store';

/* eslint-disable @typescript-eslint/explicit-function-return-type */
export function useInitScheduleToolbar(emit: any) {
  const { $config } = useStore();
  const config = $config.getConfig();

  // 默认小时间隔
  const hours = ref(Variables.default.dragInterval);
  // 默认显示天数
  const days: Ref<number | null> = ref(
    dayjs(config.endTime).diff(config.startTime, 'day'),
  );
  // 加减后的临时天数
  const tempDay = ref(15);
  // 当前激活日期
  const currentDay = ref(Variables.default.startTime);
  // 刻度
  const scale = ref(Variables.default.scaleValue);
  // 开始时间
  const scaleStartTime = ref(Variables.default.scaleRange[0]);
  // 结束时间
  const scaleEndTime = ref(Variables.default.scaleRange[1]);
  // 训练日标准
  const trainsStandards = ref(Variables.default.scaleRange.toString());
  // 是否禁用拖拽
  const allowDrag = ref(Variables.default.allowDrag);

  const onRefresh = () => {
    emit('refresh');
  };

  // 配置改变刷新
  const onConfigChangeRefresh = (_config: any = {}) => {
    emit('configChange', _config);
  };

  // 跳转到当前时间
  const onJupmToNow = () => {
    currentDay.value = new Date();
    const { startTime } = $config.getConfig();
    const time = currentDay.value.getTime() - startTime.getTime();
    const endtime = new Date($config.getConfig().endTime.getTime() + time);
    onConfigChangeRefresh({
      startTime: currentDay.value,
      endTime: endtime,
    });
  };

  // 月份改变 统一按照31天间隔进行计算
  const onMonthChange = (month: number) => {
    const time = Variables.time.millisecondOf.day * 31 * month;
    currentDay.value = new Date(currentDay.value.getTime() + time);
    const endtime = new Date($config.getConfig().endTime.getTime() + time);
    onConfigChangeRefresh({
      startTime: currentDay.value,
      endTime: endtime,
    });
  };

  // 周改变
  const onWeekChange = (week: number) => {
    const time = Variables.time.millisecondOf.week * week;
    currentDay.value = new Date(currentDay.value.getTime() + time);
    const endtime = new Date($config.getConfig().endTime.getTime() + time);
    onConfigChangeRefresh({
      startTime: currentDay.value,
      endTime: endtime,
    });
  };

  // 天改变
  const onDateChange = (day: number) => {
    const time = Variables.time.millisecondOf.day * day;
    currentDay.value = new Date(currentDay.value.getTime() + time);
    const endtime = new Date($config.getConfig().endTime.getTime() + time);
    onConfigChangeRefresh({
      startTime: currentDay.value,
      endTime: endtime,
    });
  };

  // 锁定按钮点击
  const onLockClick = () => {
    allowDrag.value = !allowDrag.value;
    onConfigChangeRefresh({
      allowDrag: allowDrag.value,
    });
  };

  // 小时改变
  const onHoursChange = (_value: number) => {
    onConfigChangeRefresh({
      dragInterval: hours.value,
    });
  };

  // 天数改变
  const onDaysChange = (_value: number) => {
    tempDay.value = days.value!;
    onConfigChangeRefresh({
      endTime: new Date(currentDay.value.getTime() + 86400000 * days.value!),
    });
  };

  // 点击增加或减少天数,最少显示天数是1天
  const onDaysClickChange = (_value: number) => {
    const tempDays = [1, 7, 15, 31];
    tempDay.value = Math.max(1, tempDay.value! + _value);
    days.value = null;
    if (tempDays.includes(tempDay.value)) {
      days.value = tempDay.value;
    }
    onConfigChangeRefresh({
      endTime: new Date(currentDay.value.getTime() + 86400000 * tempDay.value),
    });
  };

  // 训练日标准改变
  const onScaleRangeChange = (_value: string) => {
    const [start, end] = _value.split(',');
    scaleStartTime.value = Number(start);
    scaleEndTime.value = Number(end);
    onConfigChangeRefresh({
      scaleRange: [start, end],
    });
  };

  // 刻度改变
  const onScaleChange = () => {
    onConfigChangeRefresh({
      scaleValue: scale.value,
    });
  };

  // 刻度时间改变
  const onScaleTimeChange = (_value: number) => {
    if (scaleStartTime.value >= scaleEndTime.value) {
      alert('结束时间需要大于开始时间');
    } else {
      onConfigChangeRefresh({
        scaleRange: [scaleStartTime.value, scaleEndTime.value],
      });
    }
  };

  // 日期选择器改变
  const onDatePickerChange = (_value: string) => {
    const startTiem = $config.getConfig().startTime;
    const time = currentDay.value.getTime() - startTiem.getTime();
    const endtime = new Date($config.getConfig().endTime.getTime() + time);
    onConfigChangeRefresh({
      startTime: currentDay.value,
      endTime: endtime,
    });
  };

  const onSave = () => {
    emit('save');
  };

  const onSaveAs = () => {
    emit('saveAs');
  };

  return {
    days,
    scale,
    hours,
    allowDrag,
    currentDay,
    scaleEndTime,
    scaleStartTime,
    trainsStandards,
    onSave,
    onSaveAs,
    onRefresh,
    onJupmToNow,
    onLockClick,
    onWeekChange,
    onDateChange,
    onDaysChange,
    onScaleChange,
    onMonthChange,
    onHoursChange,
    onDaysClickChange,
    onScaleTimeChange,
    onScaleRangeChange,
    onDatePickerChange,
  };
}

export function useScheduleToolbarReSize(
  scheduleToolbarContentRef: Ref<HTMLCanvasElement | null>,
): { visibleArrow: Ref<boolean> } {
  // 显示箭头
  const visibleArrow = ref(false);
  // 重绘函数
  const redraw = (): void => {
    if (scheduleToolbarContentRef.value) {
      visibleArrow.value =
        scheduleToolbarContentRef.value.scrollWidth >
        scheduleToolbarContentRef.value.clientWidth + 40;
    } else {
      visibleArrow.value = false;
    }
  };

  // 防抖重绘函数
  const debouncedRedraw = debounce(redraw, 100);

  // 窗口resize防抖
  const handleResize = (): void => {
    debouncedRedraw();
  };

  // 监听 coordinateElement 的尺寸变化
  let resizeObserver: ResizeObserver | null = null;

  // 挂载后绑定事件监听
  onMounted(() => {
    if (window.ResizeObserver && scheduleToolbarContentRef.value) {
      resizeObserver = new ResizeObserver(handleResize);
      resizeObserver.observe(scheduleToolbarContentRef.value);
    }
  });

  // 移除事件监听器
  onUnmounted(() => {
    if (resizeObserver && scheduleToolbarContentRef.value) {
      resizeObserver.unobserve(scheduleToolbarContentRef.value);
      resizeObserver = null;
    }
  });

  return {
    visibleArrow,
  };
}
